home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Forever 4
/
Atari Forever 4.zip
/
Atari Forever 4.iso
/
SERIE_S
/
S_902
/
3D_PLOT
/
3D.LST
< prev
next >
Wrap
File List
|
1998-03-14
|
38KB
|
1,433 lines
DEFTEXT ,,,13
DEFNUM 4
DEFMOUSE 0
~WIND_GET(0,4,wx&,wy&,ww&,wh&)
CLIP wx&,wy&,ww&,wh&
'
DIM menu$(48)
'
erstelle_menu
init
menu:
DO
ON MENU
LOOP
'
' --- Menü erstellen ----------------------------------------------------------
PROCEDURE erstelle_menu
LOCAL i|
FOR i|=0 TO 46
READ menu$(i|)
NEXT i|
MENU menu$()
DATA 3D, Über 3D,---------------------,1,2,3,4,5,6,
DATA Datei, Funktion laden L, Funktion speichern S,-----------------------, Ende Q,
DATA Funktion, Eingeben E, Wertebereich W,--------------------, Zeichnen Z, Koordinatensystem,
DATA Darstellen, Rotation R, Entfernung D,----------------, Auflösung A,----------------, Durchsichtig, Flächig, Beleuchtet,----------------, y-anpassen,
DATA Beleuchten, Lichtquelle,-Schattierung-, Winkel, Entfernung,--------------, Rahmen,
DATA Info, Funktionen, Funktionswerte, Definitionslücken , Konstanten
ON MENU GOSUB was
ON MENU KEY GOSUB taste
RETURN
PROCEDURE init
' funktion speichern
LOCAL aufl_max|
aufl_max|=100
DIM f|(100) !Speicher für die Funktion
DIM kn(20),ko|(20) !Keller für die Zahlen und für die Operatoren
DIM zahl(30) !Speicher für die Zahlen der Funktion
' zahlp|=4 ! 0=X 1=Y 2=-X 3=-Y wird in formatiere gesetzt
DIM fun_wert(aufl_max|,aufl_max|) !Speicher für die Funktionswerte
DIM fun_wert.err!(aufl_max|,aufl_max|) !Fehler in der Funktionsberechnung
'
' Projektion
DIM bx&(aufl_max|,aufl_max|)
DIM by&(aufl_max|,aufl_max|)
' zeichnen
DIM help(aufl_max|*(aufl_max|+1))
DIM entf.order%(aufl_max|*(aufl_max|+1))
DIM hell|(aufl_max|,aufl_max|)
' (8+0.125+2+2+8+4+1)*101*101
'
DIM mesag&(15)
' Textdarstellung/editieren
DIM x&(200),y&(200)
DIM text.x&(25),text.y&(25),text$(25)
DIM edit.x&(25),edit.y&(25),edit$(25)
'
' --- Wertebereich ---
x_min=-2
x_max=2
y_min=-2
y_max=2
' --- Auflösung ---
x_aufl|=10
y_aufl|=10
verdeckt!=FALSE
beleuchtet!=FALSE
MENU 29,1
' --- Abstand ---
ges_abst=10
'
stauch_y!=TRUE
MENU 33,1
' --- Rotation ---
umz&=0
zuz&=90
neu.reihe!=TRUE
neu.projezier!=TRUE
neu.beleuchte!=TRUE
'
lich_x=0
lich_y=3
lich_z=6
'
lich.winkel!=TRUE
MENU 38,1
lich.farbanz|=9 !Konstante, Anzahl der "Farben"
' lich.entfernung!=FALSE
' lich.rahmen!
'
' Weitere Globale Variablen
xstep=(x_max-x_min)/(x_aufl|-1)
ystep=(y_max-y_min)/(y_aufl|-1)
'
cos_umz=COS(umz&/360*2*PI)
sin_umz=SIN(umz&/360*2*PI)
cos_zuz=COS(zuz&/360*2*PI)
sin_zuz=SIN(zuz&/360*2*PI)
'
x_abst=ges_abst*sin_umz*sin_zuz
y_abst=ges_abst*cos_umz*sin_zuz
z_abst=ges_abst*cos_zuz
'
neu.rechne!=TRUE
'
w_xmax&=640
w_xmin&=0
w_ymax&=400
w_ymin&=20
~WIND_GET(0,4,w_xmin&,w_ymin&,w_xmax&,w_ymax&)
ADD w_xmax&,w_xmin&-1
ADD w_ymax&,w_ymin&-1
' verdeckt!,beleuchtet!,stauch_y!
RETURN
PROCEDURE was
SELECT MENU(0)
CASE 1
ALERT 1," 3-D Funktionsplotter |=======================| | von Matthias Jüschke",1,"Weiter",d|
CASE 11
laden
CASE 12
speichern
CASE 14
ende
CASE 17
SGET bild$
funktion.eingabe
SPUT bild$
CASE 18
SGET bild$
wertebereich
SPUT bild$
CASE 20 !Zeichnen
IF LEN(f$)
rechne
proje.all
draw
ENDIF
CASE 21
IF koord_system!=FALSE
koord_system
koord_system!=TRUE
MENU 21,1
ELSE
koord_system!=FALSE
MENU 21,0
ENDIF
CASE 24
SGET bild$
rotation
SPUT bild$
CASE 25
SGET bild$
entfernung
SPUT bild$
CASE 27
SGET bild$
aufloesung
SPUT bild$
CASE 29
verdeckt!=FALSE
beleuchtet!=FALSE
MENU 29,1
MENU 30,0
MENU 31,0
CASE 30
verdeckt!=TRUE
beleuchtet!=FALSE
MENU 29,0
MENU 30,1
MENU 31,0
CASE 31
verdeckt!=FALSE
beleuchtet!=TRUE
MENU 29,0
MENU 30,0
MENU 31,1
CASE 33
IF stauch_y!
stauch_y!=FALSE
MENU 33,0
ELSE
stauch_y!=TRUE
MENU 33,1
ENDIF
neu.projezier!=TRUE
CASE 36
SGET bild$
beleuchtung
SPUT bild$
CASE 38
IF lich.winkel! AND lich.entfernung!
lich.winkel!=FALSE
MENU 38,0
ELSE
lich.winkel!=TRUE
MENU 38,1
ENDIF
neu.beleuchte!=TRUE
CASE 39
IF lich.entfernung! AND lich.winkel!
lich.entfernung!=FALSE
MENU 39,0
ELSE
lich.entfernung!=TRUE
MENU 39,1
ENDIF
neu.beleuchte!=TRUE
CASE 41
IF lich.rahmen!
lich.rahmen!=FALSE
MENU 41,0
ELSE
lich.rahmen!=TRUE
MENU 41,1
ENDIF
CASE 44
~FORM_ALERT(1,"[1][Funktionen:|SIN COS TAN COT|mit ~H: Hyperbolicusfunktionen|mit A~: Arcus-/Areafunktionen|SQRT LN LOG EXP ABS SGN][Weiter]")
CASE 45
werte_ausgeben(FALSE)
CASE 46
werte_ausgeben(TRUE)
ENDSELECT
MENU OFF
RETURN
PROCEDURE taste
SELECT ASC(UPPER$(CHR$(MENU(14))))
CASE 76 !L
laden
CASE 83 !S
speichern
CASE 81 !Q
ende
CASE 69 !E
SGET bild$
funktion.eingabe
SPUT bild$
CASE 87 !W
SGET bild$
wertebereich
SPUT bild$
CASE 90 !Z
IF LEN(f$)
rechne
proje.all
draw
ENDIF
CASE 82 !R
SGET bild$
rotation
SPUT bild$
CASE 68 !D
SGET bild$
entfernung
SPUT bild$
CASE 65 !A
SGET bild$
aufloesung
SPUT bild$
ENDSELECT
RETURN
PROCEDURE laden
FILESELECT "\*.FKT","",n$
IF EXIST(n$)
OPEN "i",#1,n$
INPUT #1,f$
CLOSE #1
IF @formatiere_f(f$,f|())<>-1
OUT 2,7
f$=""
ENDIF
neu.rechne!=TRUE
neu.projezier!=TRUE
ELSE
OUT 2,7
ENDIF
RETURN
PROCEDURE speichern
FILESELECT "\*.FKT","",n$
OPEN "o",#1,n$+".FKT"
PRINT #1,f$
CLOSE #1
RETURN
PROCEDURE ende
ALERT 2,"Programm|beenden ?",1,"Ja|Nein",f|
IF f|=1
MENU KILL
END
ENDIF
RETURN
'
' --- Funktion von f$ in ein lesbares Format in f|() bringen ------------------
FUNCTION formatiere_f(f$,VAR f|())
' Die Prozedur formatiere_f bringt die Funktion von f$ in ein Format in
' f|(), in dem die Funktion erg(x,y) die Ergebnisse errechnen kann. f(i)<200
' bedeutet, daß an der Stelle i in f eine Zahl steht. Der Wert dieser
' Zahl befindet sich in zahl(f(i)). zahl(0) bis zahl(3) steht für
' X, Y, -X und -Y; also steht z. B. f(i)=2 für die Zahl -X.
'
' Stehen in f(i) Werte größer 199 repräsentieren sie Funktionen.
' ( 200 sin: 202 cos: 203 tan: 204 cot: 205
' asin: 206 acos: 207 atan: 208 acot: 209
' sinh210,cosh211,tanh212,atanh213
' asinh214,acosh215,atanh216,acoth217
' sqrt: 218 ln: 219 log: 220
' abs: 221 sgn: 222 exp: 223
' )201
' Eine folgende Klammer auf wird nicht seperat gespeichert, SIN(X) führt
' also in f() zu f(0)=202 «SIN(», f(1)=0 «X» und f(2)=201 «)».
' Haben die Funktionen negative Vorzeichen, so wird der Wert 25 addiert.
'
' Für die Operanten gilt die Zuordnung:
' +250 -251 *252 /253 ^254
' Der Wert 255 kennzeichnet das Ende der Funktion.
'
' Die Funktion muß - wie jede Funktion - folgendermaßen aufgebaut sein:
'
' -+->+-> Wert -+-->------------>--+--------> Ende
' | | | |
' | | +-> Klammer(n) zu -+
' | | |
' | +-> funktion -+ |
' | | |
' +-------------<--+<- Operator <-+
'
' Globale Variablen werden nicht verwendet.
'
LOCAL error!,h$,kl&,fp|
zahlp|=4
h$=f$
REPEAT
IF @zahl(f$,fp|,zahlp|)
~@klzu(f$,fp|,kl&)
error!=@oper(f$,fp|)=FALSE AND f$>""
ELSE
IF @funk(f$,fp|)
INC kl&
ELSE
error!=TRUE
ENDIF
ENDIF
error!=kl&<0 OR error!
UNTIL LEN(f$)=0 OR error!
f|(fp|)=255
INC fp|
IF error! OR kl&<>0
RETURN LEN(h$)-LEN(f$)
ENDIF
RETURN -1
ENDFUNC
FUNCTION zahl(VAR f$,fp|,zahlp|)
' Die Funktion erkennt Zahlen und X bzw. Y. Bei einer Zahl wird der Zahlen-
' wert in zahl(j) gespeichert, und f(i) wird die Position der Zahl in zahl()
' gespeichert, also f(i)=j
' Bei X und Y werden die Werte automatisch in die ersten Elemente von zahl()
' geschrieben. Diese Funktion speichert in f(i), daß an der Stelle i ein
' X, Y, -X bzw. -Y steht.
' f$ wird immer um den erkannten Teil gekürzt.
' Die Funktion liefert FALSE zurück, wenn keine Zahl erkannt wurde.
LOCAL l|
'
l|=VAL?(f$)
IF l|
f|(fp|)=zahlp| !an der stelle fp| steht die zahl zahl(zahlp|)=zahl(f(fp))
INC fp|
'
zahl(zahlp|)=VAL(f$)
INC zahlp|
f$=RIGHT$(f$,LEN(f$)-l|)
RETURN TRUE
ENDIF
'
IF LEFT$(f$)="X"
f|(fp|)=0
INC fp|
f$=RIGHT$(f$,LEN(f$)-1)
RETURN TRUE
ELSE IF LEFT$(f$)="Y"
f|(fp|)=1
INC fp|
f$=RIGHT$(f$,LEN(f$)-1)
RETURN TRUE
ELSE IF LEFT$(f$,2)="-X"
f|(fp|)=2
INC fp|
f$=RIGHT$(f$,LEN(f$)-2)
RETURN TRUE
ELSE IF LEFT$(f$,2)="-Y"
f|(fp|)=3
INC fp|
f$=RIGHT$(f$,LEN(f$)-2)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNCTION funk(VAR f$,fp|)
' Diese Funktion erkennt Elementarfunktionen (mit Vorzeichen) und schreibt
' den zu der erkannten Funktion gehörigen Wert in f(i). Der zugehörige
' Wert wird von der Funktion wert() geliefert.
' f$ wird immer um den erkannten Teil gekürzt.
' Wird keine Elementarfunktion erkann, so wird FALSE zurückgeliefert.
'
LOCAL teil$,wert|,vorz!
IF ASC(f$)=ASC("-") OR ASC(f$)=ASC("+") !Vorzeichen
vorz!=(ASC(f$)=ASC("-"))
f$=RIGHT$(f$,LEN(f$)-1)
ENDIF
WHILE LEFT$(f$)=>"A" AND LEFT$(f$)<="Z"
teil$=teil$+LEFT$(f$)
f$=RIGHT$(f$,LEN(f$)-1)
WEND
wert|=@wert(teil$)
IF wert|
IF ASC(f$)=ASC("(")
teil$=teil$+LEFT$(f$)
f$=RIGHT$(f$,LEN(f$)-1) !"("
IF vorz!
ADD wert|,25
ENDIF
f|(fp|)=wert|
INC fp|
RETURN TRUE
ENDIF
ENDIF
f$=teil$+f$
RETURN FALSE
ENDFUNC
FUNCTION wert(teil$)
LOCAL wert|
IF teil$=""
wert|=200
ELSE IF teil$="SIN"
wert|=202
ELSE IF teil$="COS"
wert|=203
ELSE IF teil$="TAN"
wert|=204
ELSE IF teil$="COT"
wert|=205
ELSE IF teil$="ASIN"
wert|=206
ELSE IF teil$="ACOS"
wert|=207
ELSE IF teil$="ATAN"
wert|=208
ELSE IF teil$="ACOT"
wert|=209
ELSE IF teil$="SINH"
wert|=210
ELSE IF teil$="COSH"
wert|=211
ELSE IF teil$="TANH"
wert|=212
ELSE IF teil$="COTH"
wert|=213
ELSE IF teil$="ASINH"
wert|=214
ELSE IF teil$="ACOSH"
wert|=215
ELSE IF teil$="ATANH"
wert|=216
ELSE IF teil$="ACOTH"
wert|=217
ELSE IF teil$="SQRT"
wert|=218
ELSE IF teil$="LN"
wert|=219
ELSE IF teil$="LOG"
wert|=220
ELSE IF teil$="ABS"
wert|=221
ELSE IF teil$="SGN"
wert|=222
ELSE IF teil$="EXP"
wert|=223
ENDIF
RETURN wert|
ENDFUNC
FUNCTION oper(VAR f$,fp|)
' diese Funktion erkennt Operatoren und schreibt den zum erkannten Operator
' gehörigen Wert in f(i).
' f$ wird immer um den erkannten Teil gekürzt.
' Wird nichts erkannt, gibt die Funktion FALSE zurück.
LOCAL oper$,wert|
oper$=LEFT$(f$)
IF oper$="+"
wert|=250
ELSE IF oper$="-"
wert|=251
ELSE IF oper$="*"
wert|=252
ELSE IF oper$="/"
wert|=253
ELSE IF oper$="^"
wert|=254
ENDIF
IF wert|
f$=RIGHT$(f$,LEN(f$)-1) !bei erfolgreicher suche f$ kürzen
f|(fp|)=wert|
INC fp|
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNCTION klzu(VAR f$,fp|,kl&)
' Diese Funktion erkennt schließende Klammern, und schreibt den
' zugehörigen Wert in f(i).
' f$ wird immer um den erkannten Teil gekürzt.
' Wird nichts erkannt, gibt die Funktion FALSE zurück.
IF ASC(f$)=ASC(")")
REPEAT
f$=RIGHT$(f$,LEN(f$)-1)
f|(fp|)=201
INC fp|
DEC kl&
UNTIL ASC(f$)<>ASC(")")
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
'
' --- Funktionswerte errechnen, in fun_wert() speichern -----------------------
PROCEDURE rechne
' diese Prozedur läßt alle Funktionswerte berechnen und schreibt sie
' in fun_wert().
'
' Globale Variablen:
' x_min,x_max,y_min,y_max, x_aufl|,y_aufl|, fun_wert(),f|()
'
LOCAL xi|,yi|,x,y
t%=TIMER
'
IF neu.rechne!
ARRAYFILL fun_wert.err!(),FALSE
DEFMOUSE 2
y=y_min
FOR yi|=0 TO y_aufl|-1
x=x_min
FOR xi|=0 TO x_aufl|-1
zahl(0)=x
zahl(1)=y
zahl(2)=-x
zahl(3)=-y
fun_wert(xi|,yi|)=@erg(x,y)
ADD x,xstep
NEXT xi|
ADD y,ystep
NEXT yi|
DEFMOUSE 0
neu.rechne!=FALSE
ENDIF
t.rech&=TIMER-t%
RETURN
FUNCTION erg(x,y)
'
' Diese Funktion berechnet den zu x,y gehörigen Funktionswert.
'
' Wiederhole bis jeder Funktionsschritt abgearbeitet ist
' Wenn eine Zahl ist
' Schreibe sie in den Keller
' Sonst
' bei Klammer zu
' Wiederhole, solange im Operantenkeller ein Operant ist
' arbeite ihn mit den zugehörigen Zahlen ab
' arbeite die zur Klammer zu gehörige Funktion ab
' bei Funktionsende
' bis zum ende abarbeiten
' sonst
' Wenn der letzte Operator eine höhere Priorität hat als der folgende
' und wenn das letzte und das Folgende Operatoren sind (keine Funktion)
' dann errechne das Ergebnis
' kellere den Operator/die Funktion ab
'
' in f|() steht die Funktion
' Globale Variablen:
' f|(),kn(),ko|()
'
LOCAL knz|,koz|,i|
'
knz|=1
koz|=1
FOR i|=0 TO fp|-1
IF f|(i|)<200 !Zahl
' keller
kn(knz|)=zahl(f|(i|))
INC knz|
ELSE !keine Zahl
IF f|(i|)=201 !Klammer zu
WHILE ko|(koz|-1)>=250 !bei +-*/^
kn(knz|-2)=@rech(kn(knz|-2),ko|(koz|-1),kn(knz|-1))
DEC knz|
DEC koz|
WEND
kn(knz|-1)=@fun(ko|(koz|-1),kn(knz|-1)) !die zu ")" gehörende funktion
DEC koz|
ELSE IF f|(i|)=255 !Ende der Funktion
WHILE koz|>1
IF ko|(koz|-1)>=250
kn(knz|-2)=@rech(kn(knz|-2),ko|(koz|-1),kn(knz|-1))
DEC knz|
DEC koz|
ELSE
kn(knz|-1)=@fun(ko|(koz|-1),kn(knz|-1))
DEC koz|
ENDIF
WEND
RETURN kn(1)
ELSE ! +-*/^( oder eine Funktion
' keller
WHILE ko|(koz|-1)>=f|(i|) AND ko|(koz|-1)>=250 AND f|(i|)>=250
kn(knz|-2)=@rech(kn(knz|-2),ko|(koz|-1),kn(knz|-1))
DEC knz|
DEC koz|
WEND
ko|(koz|)=f|(i|) !abkellern
INC koz|
ENDIF
ENDIF
NEXT i|
ENDFUNC
FUNCTION rech(n1,o|,n2)
IF o|=250
RETURN n1+n2
ELSE IF o|=251
RETURN n1-n2
ELSE IF o|=252
RETURN n1*n2
ELSE IF o|=253
IF n2<>0
RETURN n1/n2
ELSE
fun_wert.err!(xi|,yi|)=TRUE
ENDIF
ELSE IF o|=254
IF INT(n2)=n2 OR n1>0
RETURN n1^n2
ELSE
fun_wert.err!(xi|,yi|)=TRUE
ENDIF
ENDIF
RETURN 0
PRINT "fehler";o|
ENDFUNC
FUNCTION fun(o|,n)
IF o|=200
RETURN n
ELSE IF o|=202 !sin
RETURN SIN(n)
ELSE IF o|=203 !cos
RETURN COS(n)
ELSE IF o|=204 !tan
RETURN TAN(n)
ELSE IF o|=205 !cotan
d=TAN(n)
IF d<>0
RETURN 1/d
ELSE
fun_wert.err!(xi|,yi|)=TRUE
ENDIF
ELSE IF o|=206 !arcsin,asin
IF ABS(n)<=1
RETURN ASIN(n)
ELSE
fun_wert.err!(xi|,yi|)=TRUE
ENDIF
ELSE IF o|=207 !arccos,acos
IF ABS(n)<=1
RETURN ACOS(n)
ELSE
fun_wert.err!(xi|,yi|)=TRUE
ENDIF
ELSE IF o|=208 !arctan,atan
RETURN ATN(n)
ELSE IF o|=209 !arccotan,acot (?)
IF n
RETURN ATN(1/n)
ELSE
fun_wert.err!(xi|,yi|)=TRUE
ENDIF
ELSE IF o|=210 !sinh
RETURN (EXP(n)-EXP(-n))/2
ELSE IF o|=211 !cosh
RETURN (EXP(n)+EXP(-n))/2
ELSE IF o|=212 !tanh
RETURN EXP(n)-EXP(-n)/(EXP(n)+EXP(-n))
ELSE IF o|=213 !coth
IF n<>0
RETURN EXP(n)+EXP(-n)/(EXP(n)-EXP(-n))
ELSE
fun_wert.err!(xi|,yi|)=TRUE
ENDIF
ELSE IF o|=214 !asinh
RETURN LOG(n+SQR(n^2+1))
ELSE IF o|=215 !acosh
IF n>=1
RETURN LOG(n+SQR(n^2-1))
ELSE
fun_wert.err!(xi|,yi|)=TRUE
ENDIF
ELSE IF o|=216 !atanh
IF ABS(n)<1
RETURN LOG((1+n)/(1-n))/2
ELSE
fun_wert.err!(xi|,yi|)=TRUE
ENDIF
ELSE IF o|=217
IF ABS(n)>1
RETURN LOG((n+1)/(n-1))/2
ELSE
fun_wert.err!(xi|,yi|)=TRUE
ENDIF
ELSE IF o|=218 !Quadratwurzel sqrt
IF n>=0
RETURN SQR(n)
ELSE
fun_wert.err!(xi|,yi|)=TRUE
ENDIF
ELSE IF o|=219 !nat. Log.
IF n>0
RETURN LOG(n)
ELSE
fun_wert.err!(xi|,yi|)=TRUE
ENDIF
ELSE IF o|=220 !10er Log.
IF n>0
RETURN LOG10(n)
ELSE
fun_wert.err!(xi|,yi|)=TRUE
ENDIF
ELSE IF o|=221 !Absolutwert
RETURN ABS(n)
ELSE IF o|=222 !Vorzeichenfunktion
RETURN SGN(n)
ELSE IF o|=223
RETURN EXP(n)
ELSE
RETURN -@fun(o|-25,n) !bei neg. vorzeichen
ENDIF
RETURN 0
PRINT "fehler";o|
ENDFUNC
PROCEDURE keller
LOCAL i|
PRINT "ko ";koz|;": ";
FOR i|=1 TO koz|
PRINT ko|(i|)'
NEXT i|
PRINT
PRINT "kn ";knz|;": ";
FOR i|=1 TO knz|
PRINT kn(i|)'
NEXT i|
PRINT
RETURN
'
' Betrachterstandpunkt:
' ges_abst - Abstand des Betrachters zum Ursprung = √(x_abst²+y_abst²+z_abst²)
' umz&, zuz& - Rotation des Betrachters um die z-Achse und zu der z-Achse
' daraus werden die folgenden Werte errechnet
' x_abst, y_abst, z_abst - Betrachterstandpunkt in den einzelnen Achsen
'
' Darstellung:
' stauch - Stauchungsfaktor, damit die Funktion die Bildschirmbreite einnimmt
' zent_x& - dient dazu, die Funktion in der Bildschirmmitte darzustellen
'
' --- Funktion darstellen -----------------------------------------------------
PROCEDURE proje.all
' Die Prozedur proje.all stellt die in fun_wert() gespeicherten Funktionswerte
' in bx&(),by&() auf Bildschirmbreite dar.
' Anschließend wird der größte und der kleinste y-Wert gesucht. Mit Hilfe
' dieser Werte wird die Funktion in y-Richtung zentriert, so daß z.B. bei
' f(x,y)=10 die Funktion nicht "über" den Bildschirm gezeichnet wird.
' Wenn die Funktion in y-Richtung angepaßt werden soll, wird mit Hilfe
' des größten und des kleinsten y-Wertes ein Faktor errechnet, mit
' dem die einzelnen Bildschirmwerte multipliziert werden, um nicht über den
' Bereich des Bildschirms zu kommen.
'
' Globale Variablen:
' x_aufl|,y_aufl|, x_min,xstep,y_min,ystep, x_abst,y_abst,z_abst
' zent_x&,zent_y&
' @projezier(),@stauch()
'
LOCAL xi|,yi|,x,y,stauch_x,stauch_y,zent_x&
LOCAL bx1&,by1&,bx2&,by2&
LOCAL by_max&,by_min&,zent_y&
'
t%=TIMER
IF neu.projezier!
by_min&=9999
by_max&=-9999
stauch_x=@stauch(zent_x&) !Stauch- und Zentrierwert errechnen
'
' --- auf den Bildschirm --------
DEFMOUSE 2
y=y_min
FOR yi|=0 TO y_aufl|-1
x=x_min
FOR xi|=0 TO x_aufl|-1
IF fun_wert.err!(xi|,yi|)=FALSE
projezier(x,y,fun_wert(xi|,yi|),bx&,by&)
bx&(xi|,yi|)=bx&
by&(xi|,yi|)=by&
by_max&=MAX(by&,by_max&)
by_min&=MIN(by&,by_min&)
ENDIF
ADD x,xstep
NEXT xi|
ADD y,ystep
NEXT yi|
' --- in y_Richtung zentrieren und ggf. Stauchen --------
'
IF by_max&-by_min&>w_ymax&-w_ymin& AND stauch_y!
stauch_y=(w_ymax&-w_ymin&)/(by_max&-by_min&)
ELSE
stauch_y=1
ENDIF
zent_y&=stauch_y*(by_max&+by_min&)/2-(w_ymax&+w_ymin&)/2
'
FOR yi|=0 TO y_aufl|-1
FOR xi|=0 TO x_aufl|-1
IF fun_wert.err!(xi|,yi|)=FALSE
IF stauch_y!
by&(xi|,yi|)=by&(xi|,yi|)*stauch_y
bx&(xi|,yi|)=(bx&(xi|,yi|)-(w_xmax&+w_xmin)/2)*stauch_y+(w_xmax&+w_xmin&)/2
ENDIF
SUB by&(xi|,yi|),zent_y&
ENDIF
NEXT xi|
NEXT yi|
neu.projezier!=FALSE
ENDIF
t.proj&=TIMER-t%
DEFMOUSE 0
RETURN
PROCEDURE projezier(x,y,z,VAR bx&,by&)
' Diese Funktion projeziert den Punkt P(x,y,z) auf die Bildschirmebene
' in bx&,by&. x-,y-,z_abst geben den Abstand vom Ursprung an; stauch_x
' ist ein Faktor, der dazu dient, die Bildbreite möglichst günstig auszu-
' nutzen, zent_x& dient dazu, die Werte nicht zu weit links oder rechts
' zu zeichnen.
' sin/cos_umz/zuz sind die Sinus/Cosinuswerte, mit deren hilfe die Funktion
' gedreht wird.
'
' Global:
' y_abst,x_abst,z_abst
' cos_umz,sin_umz,sin_zuz,cos_zuz
' zent_x&,stauch_x
'
LOCAL flucht
'
' ??? gehört zu x,y - oder + ???
flucht=SQR((x_abst+x)^2+(y_abst+y)^2+(z_abst+z)^2)/stauch_x
' flucht wird auch noch in @stauch() berrechnet
'
bx&=zent_x&+(x*cos_umz-y*sin_umz)/flucht
by&=(w_ymax&+w_ymin&)/2-(z*sin_zuz+(x*sin_umz+y*cos_umz)*cos_zuz)/flucht
RETURN
'
PROCEDURE koord_system
' Diese Prozedur zeichnet das Koordinatensystem auf den Bildschrim.
' klen gibt die Länge mit der die Achsen des Koordinatensystems gezeichnet
' werden an.
'
' Globale:
' @projezier(),benötigt zent_x&,stauch_x
'
LOCAL klen,bx&,by&,zent_x&,stauch_x
'
stauch_x=@stauch(zent_x&) !Stauch- und Zentrierwert errechnen
'
klen=(x_max+y_max)/4
'
DEFLINE (&X10101010101010101010101010101011),1,0,1
DEFTEXT ,,,6
'
projezier(klen,0,0,bx&,by&)
LINE zent_x&,(w_ymax&+w_ymin&)/2,bx&,by&
TEXT bx&,by&+8,"x"
'
projezier(0,klen,0,bx&,by&)
LINE zent_x&,(w_ymax&+w_ymin&)/2,bx&,by&
TEXT bx&,by&+8,"y"
'
projezier(0,0,klen,bx&,by&)
LINE zent_x&,(w_ymax&+w_ymin&)/2,bx&,by&
TEXT bx&-3,by&-2,"z"
'
DEFLINE 1,0,0,0
DEFTEXT ,,,13
RETURN
FUNCTION stauch(VAR zent_x&)
' Es wird ein Faktor errechnet, mit dem die Funktion auf die Bildschirmbreite
' angepaßt wird.
' Zusätzlich wird ein Wert errechnet, der die Funktion in der Bildmitte
' platziert.
'
LOCAL flucht1,flucht2,flucht3,flucht4
LOCAL bild_x_min,bild_x_max,stauch_x
stauch_x=1
zent_x&=0
'
flucht1=SQR((x_abst+x_min)^2+(y_abst+y_min)^2+(z_abst-fun_wert(0,0))^2)
flucht2=SQR((x_abst+x_max)^2+(y_abst+y_min)^2+(z_abst-fun_wert(x_aufl|-1,0))^2)
flucht3=SQR((x_abst+x_min)^2+(y_abst+y_max)^2+(z_abst-fun_wert(0,y_aufl|-1))^2)
flucht4=SQR((x_abst+x_max)^2+(y_abst+y_max)^2+(z_abst-fun_wert(x_aufl|-1,y_aufl|-1))^2)
'
bild_x_min=MIN((x_min*cos_umz-y_min*sin_umz)/flucht1,(x_max*cos_umz-y_min*sin_umz)/flucht2,(x_min*cos_umz-y_max*sin_umz)/flucht3,(x_max*cos_umz-y_max*sin_umz)/flucht4)
bild_x_max=MAX((x_min*cos_umz-y_min*sin_umz)/flucht1,(x_max*cos_umz-y_min*sin_umz)/flucht2,(x_min*cos_umz-y_max*sin_umz)/flucht3,(x_max*cos_umz-y_max*sin_umz)/flucht4) !**muß für drehungen evt noch mehr enthalten
'
stauch_x=(w_xmax&-w_xmin&)/(bild_x_max-bild_x_min)
zent_x&=(w_xmax&+w_xmin&)/2-(bild_x_max+bild_x_min)/2*stauch_x
RETURN stauch_x
ENDFUNC
PROCEDURE draw
DEFFILL 1,0,0
PBOX -1,18,640,400
' PRINT AT(1,3);"Gerechnet: ";t.rech&/200
' PRINT "Projeziert: ";t.proj&/200
IF beleuchtet! AND lich.rahmen!=FALSE
BOUNDARY 0
ELSE
BOUNDARY 1
ENDIF
IF verdeckt! OR beleuchtet!
IF neu.reihe!
reihenfolge(help())
ENDIF
IF beleuchtet!
IF neu.beleuchte!
beleuchte(help())
ENDIF
t%=TIMER
draw.beleuchtet
ELSE
t%=TIMER
DEFFILL 1,0,0
draw.verdeckt
ENDIF
ELSE
t%=TIMER
draw.draht
ENDIF
t.draw&=TIMER-t%
IF koord_system!
koord_system
ENDIF
' PRINT "Abstand: ";t.entf&/200
' PRINT "Licht: ";t.lich&/200
' PRINT "Zeichnen: ";t.draw&/200
CLR t.draw&,t.entf&,t.lich&,t.proj&,t.rech&
RETURN
PROCEDURE reihenfolge(VAR entf.punkt())
LOCAL x_anf,x_pos,y_pos,x|,nr&,nr_end&
' Diese Prozedur ermittelt den Abstand (in x-y-Richtung) der einzelnen Felder
' vom Betrachter in entf.punkt(). entf.order%() ist ein durchnummeriertes
' Feld. Nachdem alle Abstände ermittlet wurden, wird entf.punkt() so sortiert,
' daß die am weitesten entfernten Felder an erster Stelle stehen. Zudem
' werden in gleicher Weise die Werte von entf.order%() getauscht, so daß
' das Feld, das entf.order%(n) darstellt, als n-tes gezeichnet werden soll.
'
' --- Berechnen der Entfernung vom Betrachter ----
t%=TIMER
IF neu.reihe!
x_anf=x_min+xstep/2+x_abst
y_pos=y_min+ystep/2+y_abst
x_pos=x_anf
nr_end&=(x_aufl|-1)*(y_aufl|-1)
REPEAT
entf.punkt(nr&)=x_pos^2+y_pos^2
INC x|
ADD x_pos,xstep
IF x|=x_aufl|-1
ADD y_pos,ystep
x_pos=x_anf
x|=0
ENDIF
entf.order%(nr&)=nr&
INC nr&
UNTIL nr&=nr_end&
QSORT entf.punkt(-),nr_end&,entf.order%()
neu.reihe!=FALSE
ENDIF
t.entf&=TIMER-t%
RETURN
PROCEDURE beleuchte(VAR d())
LOCAL xi|,yi|,lich_ges,nr&,d_min,d_max
' Im ersten Teil wird der Abstand der Flächen zur Lichtquelle bestimmt
' und gespeichert, und es wird (wenn nötig) der Winkel, den die Fläche zur
' Lichtquelle einnimmt gespeichert.
' Wenn die Helligkeit auch nach der Entfernung bestimmt werden soll wird
' im zweiten Teil wird jeder Entfernung ein Helligkeitswert zugewiesen.
' Wenn auch der Winkel die Helligkeit bestimmt, wird der Entfernungswert
' mit dem Winkelwert multipliziert, da die Helligkeitswerte dann natürlich
' zu groß werden, ist die Wurzel des erhaltenen wertes die Helligkeit.
' Je größer der Wert in hell|(), um so heller ist das entsprechende Feld.
'
' d(): Abstand der Lichtquelle zum beleuchteten Feld
t%=TIMER
IF neu.beleuchte!
ON ERR GOSUB lich.err
' --- Winkel und Abstand werden errechnet -----------------
nr&=0
d_min=9999
d_max=-9999
' ARRAYFILL hell|(),1
lich_ges=lich_x^2+lich_y^2+lich_z^2
x_anf=x_min+xstep/2
y_pos=y_min+ystep/2
FOR yi|=0 TO y_aufl|-2
x_pos=x_anf
FOR xi|=0 TO x_aufl|-2
IF fun_wert.err!(xi|,yi|)=FALSE AND fun_wert.err!(xi|+1,yi|)=FALSE AND fun_wert.err!(xi|,yi|+1)=FALSE
' d: (Länge der Strecke Lichtpunkt - Feldpunkt)^2
d(nr&)=(lich_x-x_pos)^2+(lich_y-y_pos)^2+(lich_z-fun_wert(xi|,yi|))^2
d_min=MIN(d(nr&),d_min)
d_max=MAX(d(nr&),d_max)
'
IF lich.winkel!
' der Normalenvektor der berechneten Fläche
nx=-(fun_wert(xi|+1,yi|)-fun_wert(xi|,yi|))/xstep
ny=-(fun_wert(xi|,yi|+1)-fun_wert(xi|,yi|))/ystep
nz=1
' cos: cos vom winkel zw. Normalen und Lichtpunkt-Feldpunkt-Vektor
cos=(lich_x-x_pos)*nx+(lich_y-y_pos)*ny+(lich_z-fun_wert(xi|,yi|))*nz
cos=cos/SQR(d(nr&)*(nx^2+ny^2+nz^2))
'
hell|(xi|,yi|)=ABS(cos*lich.farbanz|) !stark beschienen - kl.hell|()
ENDIF
ENDIF
ADD x_pos,xstep
INC nr&
NEXT xi|
ADD y_pos,ystep
NEXT yi|
'
IF lich.entfernung!
' --- zum Abstand gehörende Helligkeit wird errechnet --------
nr&=0
d_sumand=-d_min
d_faktor=lich.farbanz|/(d_max-d_min)
FOR yi|=0 TO y_aufl|-2
FOR xi|=0 TO x_aufl|-2
ADD d(nr&),d_sumand
IF lich.winkel!
hell|(xi|,yi|)=SQR(hell|(xi|,yi|)*(lich.farbanz|-d_faktor*d(nr&)))
ELSE
hell|(xi|,yi|)=lich.farbanz|-d_faktor*d(nr&) !gr. d - kl. hell|()
ENDIF
INC nr&
NEXT xi|
NEXT yi|
ENDIF
neu.beleuchte!=FALSE
ON ERROR
ENDIF
t.lich&=TIMER-t%
RETURN
PROCEDURE lich.err
ON ERROR GOSUB lich.err
ALERT 1,"Fehler "+STR$(ERR)+"|ist aufgetreten!",1,"Weiter|Menü",d|
IF d|=1
RESUME NEXT
ELSE
RESUME menu
ENDIF
RETURN
'
PROCEDURE draw.draht
LOCAL xi|,yi|
' Globale Variablen:
' x_aufl|,y_aufl|,bx&(),by&()
'
FOR yi|=0 TO y_aufl|-1
FOR xi|=0 TO x_aufl|-1
IF fun_wert.err!(xi|,yi|)=FALSE
IF xi|
IF fun_wert.err!(xi|-1,yi|)=FALSE
LINE bx&(xi|-1,yi|),by&(xi|-1,yi|),bx&(xi|,yi|),by&(xi|,yi|)
ENDIF
ENDIF
IF yi|
IF fun_wert.err!(xi|,yi|-1)=FALSE
LINE bx&(xi|,yi|-1),by&(xi|,yi|-1),bx&(xi|,yi|),by&(xi|,yi|)
ENDIF
ENDIF
ENDIF
NEXT xi|
NEXT yi|
RETURN
PROCEDURE draw.verdeckt
LOCAL nr&,nr_end&,x|,y|
' Globale Variablen:
' x_aufl|,entf.order%()
'
nr_end&=(x_aufl|-1)*(y_aufl|-1)
REPEAT
x|=entf.order%(nr&) MOD (x_aufl|-1)
y|=entf.order%(nr&) DIV (x_aufl|-1)
IF fun_wert.err!(x|,y|)=FALSE
IF fun_wert.err!(x|+1,y|)=FALSE
IF fun_wert.err!(x|,y|+1)=FALSE
IF fun_wert.err!(x|+1,y|+1)=FALSE
polyfill(lich.farbanz|,x|,y|)
ENDIF
ENDIF
ENDIF
ENDIF
INC nr&
UNTIL nr&=nr_end&
RETURN
PROCEDURE draw.beleuchtet
LOCAL nr&,nr_end&,x|,y|
' Globale Variablen:
' x_aufl|,entf.order%()
'
nr_end&=(x_aufl|-1)*(y_aufl|-1)
REPEAT
x|=entf.order%(nr&) MOD (x_aufl|-1)
y|=entf.order%(nr&) DIV (x_aufl|-1)
IF fun_wert.err!(x|,y|)=FALSE
IF fun_wert.err!(x|+1,y|)=FALSE
IF fun_wert.err!(x|,y|+1)=FALSE
IF fun_wert.err!(x|+1,y|+1)=FALSE
polyfill(hell|(x|,y|),x|,y|)
ENDIF
ENDIF
ENDIF
ENDIF
INC nr&
UNTIL nr&=nr_end&
RETURN
PROCEDURE polyfill(color|,xi|,yi|)
color|=lich.farbanz|-color|
IF color|<1
DEFFILL 1,0,0
ELSE
DEFFILL 1,2,MIN(color|,8)
ENDIF
x&(0)=bx&(xi|+1,yi|+1)
x&(1)=bx&(xi|,yi|+1)
x&(2)=bx&(xi|,yi|)
x&(3)=bx&(xi|+1,yi|)
x&(4)=bx&(xi|+1,yi|+1)
' x&(5)=bx&(xi|,yi|)
y&(0)=by&(xi|+1,yi|+1)
y&(1)=by&(xi|,yi|+1)
y&(2)=by&(xi|,yi|)
y&(3)=by&(xi|+1,yi|)
y&(4)=by&(xi|+1,yi|+1)
' y&(5)=by&(xi|,yi|)
POLYFILL 5,x&(),y&()
RETURN
'
' Bildschirm:
' z-Achse
' ∧
' |
' | ¬ y-Achse
' |/
' +------>
' x-Achse
'
PROCEDURE funktion.eingabe
LOCAL d&,rueck&
@text.set(0,0,0,"f(x,y)=")
@edit.set(0,0,0,f$)
wind.name$=" Funktion eingeben "
'
REPEAT
eingabe(2,edit.x&(),edit.y&(),edit$())
f$=UPPER$(edit$(0))
rueck&=@formatiere_f(f$,f|())
IF rueck&<>-1
ALERT 1,"Fehler an Stelle "+STR$(rueck&),1,"Weiter",d&
ENDIF
UNTIL rueck&=-1
neu.rechne!=TRUE
neu.projezier!=TRUE
neu.beleuchte!=TRUE
RETURN
PROCEDURE rotation
@text.set(0,0,0,"Rotation um die z-Achse:")
@edit.set(0,0,0,STR$(umz&))
@text.set(1,0,1,"Neigung zur z-Achse :")
@edit.set(1,0,1,STR$(zuz&))
wind.name$=" Rotationen "
'
eingabe(2,edit.x&(),edit.y&(),edit$())
'
umz&=VAL(edit$(0))
zuz&=VAL(edit$(1))
'
cos_umz=COS(umz&/360*2*PI)
sin_umz=SIN(umz&/360*2*PI)
cos_zuz=COS(zuz&/360*2*PI)
sin_zuz=SIN(zuz&/360*2*PI)
x_abst=ges_abst*sin_umz*sin_zuz
y_abst=ges_abst*cos_umz*sin_zuz
z_abst=ges_abst*cos_zuz
neu.reihe!=TRUE
neu.projezier!=TRUE
RETURN
PROCEDURE entfernung
@text.set(0,0,0,"Entfernung vom Ursprung:")
@edit.set(0,0,0,STR$(ges_abst))
wind.name$=" Entfernung "
'
eingabe(1,edit.x&(),edit.y&(),edit$())
'
ges_abst=VAL(edit$(0))
x_abst=ges_abst*sin_umz*sin_zuz
y_abst=ges_abst*cos_umz*sin_zuz
z_abst=ges_abst*cos_zuz
neu.reihe!=TRUE
neu.projezier!=TRUE
RETURN
PROCEDURE wertebereich
LOCAL ok!
@text.set(0,0,0,"x-Minimum:")
@edit.set(0,0,0,STR$(x_min))
@text.set(1,0,1,"x-Maximum:")
@edit.set(1,0,1,STR$(x_max))
@text.set(2,0,2,"y-Minimum:")
@edit.set(2,0,2,STR$(y_min))
@text.set(3,0,3,"y-Maximum:")
@edit.set(3,0,3,STR$(y_max))
wind.name$=" Wertebereich "
'
REPEAT
eingabe(3,edit.x&(),edit.y&(),edit$())
x_min=VAL(edit$(0))
x_max=VAL(edit$(1))
y_min=VAL(edit$(2))
y_max=VAL(edit$(3))
ok!=x_min<x_max AND y_min<y_max
IF ok!=0
ALERT 1,"Falscher Wertebereich!",1,"Weiter",d&
ENDIF
UNTIL ok!
xstep=(x_max-x_min)/(x_aufl|-1)
ystep=(y_max-y_min)/(y_aufl|-1)
neu.rechne!=TRUE
neu.projezier!=TRUE
neu.beleuchte!=TRUE
RETURN
PROCEDURE aufloesung
@text.set(0,0,0,"Auflösung in x-Richtung:")
@edit.set(0,0,0,STR$(x_aufl|))
@text.set(1,0,1," y-Richtung:")
@edit.set(1,0,1,STR$(y_aufl|))
wind.name$=" Auflösung "
'
eingabe(1,edit.x&(),edit.y&(),edit$())
x_aufl|=MAX(MIN(VAL(edit$(0)),100),2) ! 2 bis 100
y_aufl|=MAX(MIN(VAL(edit$(1)),100),2)
xstep=(x_max-x_min)/(x_aufl|-1)
ystep=(y_max-y_min)/(y_aufl|-1)
neu.rechne!=TRUE
neu.reihe!=TRUE
neu.projezier!=TRUE
neu.beleuchte!=TRUE
RETURN
PROCEDURE beleuchtung
@text.set(0,0,0,"Position der Beleuchtungsquelle:")
@text.set(1,0,1,"x-Richtung:")
@edit.set(0,0,1,STR$(lich_x))
@text.set(2,0,2,"y-Richtung:")
@edit.set(1,0,2,STR$(lich_y))
@text.set(3,0,3,"z-Richtung:")
@edit.set(2,0,3,STR$(lich_z))
wind.name$="Beleuchtung"
'
eingabe(2,edit.x&(),edit.y&(),edit$())
lich_x=VAL(edit$(0))
lich_y=VAL(edit$(1))
lich_z=VAL(edit$(2))
neu.beleuchte!=TRUE
RETURN
PROCEDURE werte_ausgeben(luecken!)
LOCAL xi|,yi|,i&,n&,x|,y|
LOCAL exit!
'
DEFFILL 0,0,0
PBOX 0,20,640,400
IF neu.rechne!=FALSE
FOR yi|=0 TO y_aufl|-1
FOR xi|=0 TO x_aufl|-1
IF (fun_wert.err!(xi|,yi|) XOR NOT luecken!)
x|=(i& MOD 15)+1
y|=(i& DIV 15)*26
IF luecken!
text.set(x|,y|,x|,STR$(x_min+xi|*xstep)+", "+STR$(y_min+yi|*ystep))
ELSE
text.set(x|,y|,x|,"("+STR$(x_min+xi|*xstep)+","+STR$(y_min+yi|*ystep)+","+STR$(fun_wert(xi|,yi|))+")")
ENDIF
INC i&
INC n&
IF i&>=45
IF luecken!
text.set(0,0,0,"Auf Definitionslücken wurden an folgenden Stellen zugegriffen:")
ELSE
text.set(0,0,0,"Funktionspunkte:")
ENDIF
exit!=INP(2)=27
DEFFILL 0,0,0
PBOX 0,20,640,400
i&=0
ENDIF
ENDIF
EXIT IF exit!
NEXT xi|
EXIT IF exit!
NEXT yi|
ENDIF
IF i& AND neu.rechne!=FALSE
IF luecken!
text.set(0,0,0,"Auf Definitionslücken wurden an folgenden Stellen zugegriffen:")
text.set(0,16,16,STR$(n&)+" nicht def. Stellen ausgegeben.")
ELSE
text.set(0,0,0,"Funktionspunkte:")
text.set(0,16,16,STR$(n&)+" Funktionswerte ausgegeben.")
ENDIF
~INP(2)
ELSE
IF luecken!
text.set(0,0,0,"Es wurde nicht auf undefinierte Stellen zugegriffen!")
ELSE
text.set(0,0,0,"Funktionswerte noch nicht errechnet!")
ENDIF
~INP(2)
ENDIF
DEFFILL 0,0,0
PBOX 0,20,640,400
RETURN
'
PROCEDURE text.set(n|,x&,y&,text$)
text.x&(n|)=x&*8+16
text.y&(n|)=y&*16+38
TEXT text.x&(n|),text.y&(n|),text$
text$(n|)=text$
RETURN
PROCEDURE edit.set(n|,x&,y&,edit$)
edit.x&(n|)=LEN(text$(y&))*8+16
edit.y&(n|)=y&*16+38
TEXT edit.x&(n|),edit.y&(n|),edit$
edit$(n|)=edit$
RETURN
'
PROCEDURE eingabe(n|,VAR edit.x&(),edit.y&(),edit$())
' h&=WIND_CREATE(&X1011,0,0,0,0)
' ~wind_set(
' ~WIND_OPEN(h&,100,19,200,100)
'
edit(n|,edit.x&(),edit.y&(),edit$())
'
' ~WIND_CLOSE(h&)
' ~WIND_DELETE(h&)
RETURN
PROCEDURE edit(n|,VAR edit.x&(),edit.y&(),edit$())
' Die Prozedur ermöglicht die Eingabe bzw. das Editieren von n Strings,
' in edit$() stehen. Die Bildschirmpositionen der einzelnen Strings stehen
' in edit.x&() und edit.y&().
' Interrupts der Tastatur und Menü/Fenster werden abgefragt.
' evt sollte i und cr auch übergeben werden
'
LOCAL undo$,key%,d&,asc|,cr|,i|,evnts&
i|=0
undo$=edit$(i|)
cr|=LEN(edit$(i|))
REPEAT
cursor(edit.x&(i|)+cr|*8,edit.y&(i|),TRUE)
' evnts&=EVNT_MULTI(&X10001,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,mes&,key&,d&,d&,d&,d&)
evnts&=1
key%=GEMDOS(7)
cursor(edit.x&(i|)+cr|*8,edit.y&(i|),FALSE)
IF evnts&=1 !Tastatur
asc|=key% MOD 256
scan|=(key%/65536) MOD 256
SELECT scan|
CASE 75
IF cr| !<-
DEC cr|
ENDIF
CASE 77
IF cr|<LEN(edit$(i|)) !->
INC cr|
ENDIF
CASE 14
IF cr| !Backspace
edit$(i|)=LEFT$(edit$(i|),cr|-1)+RIGHT$(edit$(i|),LEN(edit$(i|))-cr|)
DEC cr|
ENDIF
CASE 83
IF cr|<LEN(edit$(i|)) !Delete
edit$(i|)=LEFT$(edit$(i|),cr|)+RIGHT$(edit$(i|),LEN(edit$(i|))-cr|-1)
ENDIF
CASE 97
IF LEN(undo$)
edit$(i|)=undo$
cr|=LEN(edit$(i|))
ENDIF
CASE 72
IF i| !v
DEC i|
undo$=edit$(i|)
cr|=LEN(edit$(i|))
ENDIF
CASE 80
IF i|<n| !∧
INC i|
undo$=edit$(i|)
cr|=LEN(edit$(i|))
ENDIF
DEFAULT
IF asc|>31 AND LEN(edit$(i|))<255
edit$(i|)=LEFT$(edit$(i|),cr|)+CHR$(asc|)+RIGHT$(edit$(i|),LEN(edit$(i|))-cr|)
INC cr|
ENDIF
ENDSELECT
TEXT edit.x&(i|),edit.y&(i|),edit$(i|)+" "
ELSE IF evnts&=16 !Message
ENDIF
UNTIL asc|=13 OR asc|=27
RETURN
PROCEDURE cursor(x&,y&,setzen!)
BOUNDARY 0
GRAPHMODE 3
DEFFILL 1,1,1
PBOX x&,y&+2,x&+7,y&-13
GRAPHMODE 1
BOUNDARY 1
RETURN